package org.apache.hadoop.security;

import com.ideal.security.conf.IdealHadoopConfiguration;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.security.UserGroupInformation.AuthenticationMethod;

import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
import java.io.IOException;
import java.security.PrivilegedAction;

public class IdealUGITool {

    private static final Log LOG = LogFactory.getLog(IdealUGITool.class);
    private static final String DOMAIN = "EXAMPLE.COM";

    /**
     * 使用密码的方式认证principal
     * @param username
     * @param password
     * @return
     */
    public static UserGroupInformation getVerifiedUgiByPwd(String username,
                                                           final String password) {
        Subject subject = new Subject();
        LoginContext login = null;
        CallbackHandler handler = new CallbackHandler() {
            public void handle(Callback[] callbacks) throws IOException,
                    UnsupportedCallbackException {
                for (Callback callback : callbacks) {
                    if (callback instanceof PasswordCallback) {
                        PasswordCallback pc = (PasswordCallback) callback;
                        pc.setPassword(password.toCharArray());
                    }
                }
            }
        };
        try {
            IdealHadoopConfiguration ihc = new IdealHadoopConfiguration();
            ihc.setPrincipal(username + "@" + DOMAIN);
            login = new LoginContext("hadoop-user-kerberos",
                    subject, handler, ihc);
            login.login();
			
			/*Subject loginSubject = login.getSubject();
		    Set<Principal> loginPrincipals = loginSubject.getPrincipals();
			
		    User ugiUser = new User(loginPrincipals.iterator().next().getName(),
		            AuthenticationMethod.KERBEROS, login);
		        loginSubject.getPrincipals().add(ugiUser);
		        UserGroupInformation ugi = new UserGroupInformation(loginSubject);
		        // ugiUser.setLogin(login);
		        ugi.setAuthenticationMethod(AuthenticationMethod.KERBEROS);
		        return ugi;*/
            UserGroupInformation ugi = new UserGroupInformation(subject);
            subject.getPrincipals(User.class).iterator().next().setLogin(login);
            ugi.setAuthenticationMethod(AuthenticationMethod.KERBEROS);
            ugi = new UserGroupInformation(login.getSubject());

            return ugi;

        } catch (LoginException e) {
            e.printStackTrace();
            return null;
        }
		/*UserGroupInformation loginUser = new UserGroupInformation(subject);
		// loginUser.setLogin(login);
		subject.getPrincipals(User.class).iterator().next().setLogin(login);
		loginUser.setAuthenticationMethod(AuthenticationMethod.KERBEROS);
		loginUser = new UserGroupInformation(login.getSubject());

		if (LOG.isDebugEnabled()) {
			LOG.debug("loginUser.getShortUserName():"
					+ loginUser.getShortUserName());
			LOG.debug("loginUser.getUserName() " + loginUser.getUserName());
		}
		return loginUser;*/
    }

    public static void main(String[] args) throws IOException {
        UserGroupInformation ugi = IdealUGITool.getVerifiedUgiByPwd("gdpi", "mkjd6RT");
        //UserGroupInformation ugi = UserGroupInformation.getUGIFromTicketCache("/tmp/krb5cc_501", "gdpi@EXAMPLE.COM");
        ugi.doAs(new PrivilegedAction<String>() {
            @Override
            public String run(){
                try {
                    Runtime.getRuntime().exec("hadoop jar /usr/lib/hadoop-mapreduce/hadoop-mapreduce-examples-2.3.0-cdh5.0.0.jar wordcount /user/gdpi/private/in /user/gdpi/private/out");
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return "okay";
            }
        });
    }

}
